{
  "openapi": "3.1.0",
  "info": {
    "title": "Cloud Storage Open API",
    "description": "Gerencie os arquivos, envios, exclusões e rótulos de arquivo do armazenamento na nuvem do MoreLogin pela MoreLogin Open API.\n\n**URL base**: `https://api.morelogin.com`\n\nA autenticação é feita por token Bearer OAuth2. Consulte [Autenticação](../Getting%20Started/authentication.md) para mais detalhes.\n",
    "version": "2026-09-05"
  },
  "servers": [
    {
      "url": "https://api.morelogin.com"
    }
  ],
  "tags": [
    {
      "name": "Cloud Storage",
      "description": "Consultar cota e uso do armazenamento"
    },
    {
      "name": "Cloud Storage Files",
      "description": "Consultar, enviar e excluir arquivos do armazenamento em nuvem"
    },
    {
      "name": "Cloud Storage File Tags",
      "description": "Gerenciar tags associadas a arquivos do armazenamento em nuvem"
    }
  ],
  "x-tagGroups": [
    {
      "name": "Cloud Storage",
      "tags": [
        "Cloud Storage",
        "Cloud Storage Files",
        "Cloud Storage File Tags"
      ]
    }
  ],
  "paths": {
    "/cloudstorage/info": {
      "get": {
        "summary": "Consultar informações do armazenamento em nuvem",
        "description": "Retorna a cota de Cloud Storage da equipe e o uso atual.\n- **Pré-requisitos**: a equipe precisa já ter um registro de Cloud Storage. **Uma equipe que nunca teve Cloud Storage provisionado recebe um erro, não uma leitura de capacidade zero** — o registro é criado na compra do armazenamento, não de forma preguiçosa por esta chamada.\n- **Efeito**: nenhum. Somente leitura. É seguro repetir com recuo limitado.\n- **Unidades**: `capacity` e `usedCapacity` são contagens de bytes.\n- **Precisão**: `usedCapacity` é um contador acumulado mantido no envio e na exclusão, não uma soma ao vivo sobre a tabela de arquivos, então pode divergir do total de `fileSize` em `/cloudstorage/file/page`.\n- **Valores**: `capacityStatus` é `1` apenas quando uma cota positiva está totalmente consumida; `isExpired` compara a data de expiração com o momento atual. Arquivos cujo envio nunca foi confirmado não contam para `usedCapacity`.\n\nErros de negócio documentados: `39001`. Consulte [Error Codes](../Getting%20Started/error-codes.md) para o significado de cada código. Qualquer operação também pode retornar os códigos comuns.",
        "operationId": "queryCloudStorageInfo",
        "tags": [
          "Cloud Storage"
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/StorageInfoResponse"
          }
        }
      }
    },
    "/cloudstorage/file/page": {
      "post": {
        "summary": "Paginar arquivos do armazenamento em nuvem",
        "description": "Lista os arquivos do Cloud Storage, página por página.\n- **Efeito**: nenhum. Somente leitura. É seguro repetir com recuo limitado.\n- **Visibilidade**: **só são listados os arquivos cujo envio foi confirmado**: um arquivo com uma URL pré-assinada que nunca foi concluída não aparece. Membros sem a permissão de todos os dados veem apenas os arquivos que eles mesmos enviaram.\n- **Filtragem**: `fileName` admite correspondência parcial; `tagIds` é uma correspondência OR; os resultados são ordenados do mais novo para o mais antigo e essa ordem não pode ser alterada.\n- **Ressalva**: uma entrada de `tagInfo` pode ser null quando uma etiqueta foi excluída enquanto ainda estava vinculada ao arquivo.",
        "operationId": "pageCloudStorageFiles",
        "tags": [
          "Cloud Storage Files"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FilePageRequest"
              },
              "example": {
                "pageNo": 1,
                "pageSize": 20,
                "fileName": "report",
                "tagIds": [
                  "1800000000000001"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/FilePageResponse"
          }
        }
      }
    },
    "/cloudstorage/upload/init": {
      "post": {
        "summary": "Solicitar em lote URLs de upload pré-assinadas",
        "description": "Reserva registros do Cloud Storage e obtém URLs de envio pré-assinadas.\n- **Pré-requisitos**: a equipe precisa ter um registro de Cloud Storage e ele não pode estar expirado. Cada nome base de arquivo é limitado a 60 caracteres e precisa ser único tanto dentro da requisição quanto em relação a todos os arquivos existentes da equipe — **a comparação é feita pelo nome sem a extensão**, então `a.png` colide com um `a.mp4` existente.\n- **Limites**: no máximo 100 envios podem ficar sem confirmação ao mesmo tempo em toda a equipe.\n- **Efeito**: insere um registro por nome com status de envio em andamento e tamanho zero, e retorna `{id, fileName, presignedUrl}` para cada um.\n- **Cota**: **o espaço não é verificado aqui.** Ele é cobrado quando você confirma o envio, então o init pode ter sucesso e o complete ainda falhar por falta de espaço.\n- **Conclusão**: sincrônica. **Cada URL pré-assinada é válida por uma hora**; envie os bytes com `PUT` e depois chame `/cloudstorage/upload/complete`.\n\nErros de negócio documentados: `39001`, `39037`, `39044`, `39045`, `39047`, `39050`, `39051`. Consulte [Error Codes](../Getting%20Started/error-codes.md) para o significado de cada código. Qualquer operação também pode retornar os códigos comuns.",
        "operationId": "batchRequestCloudStoragePresignedUploadUrls",
        "tags": [
          "Cloud Storage Files"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadInitRequest"
              },
              "example": {
                "fileNames": [
                  "example.jpg",
                  "docs/report.pdf"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/UploadInitResponse"
          }
        }
      }
    },
    "/cloudstorage/upload/complete": {
      "post": {
        "summary": "Confirmar conclusão do upload",
        "description": "Confirma um arquivo do Cloud Storage já enviado.\n- **Pré-requisitos**: o registro do arquivo precisa pertencer à sua equipe e o objeto precisa já estar no armazenamento — o serviço lê o ETag e o comprimento dele para verificar. O tamanho precisa ser maior que 0 e menor que 2 GB.\n- **Efeito**: cobra a cota de armazenamento da equipe de forma atômica, depois marca o registro como enviado e guarda o tamanho real. Até isso ter sucesso o arquivo **não aparece em `/cloudstorage/file/page`** e continua ocupando uma das 100 vagas pendentes.\n- **Em caso de falha o objeto enviado é excluído.** Chamar isso cedo demais, acima do limite de tamanho ou sem espaço livre remove os bytes do armazenamento e deixa o registro sem confirmação. A recuperação é um `/cloudstorage/upload/init` novo e reenviar, não repetir esta chamada.\n- **Conclusão**: sincrônica e idempotente depois de ter tido sucesso — uma segunda chamada retorna o mesmo arquivo sem cobrar cota novamente.\n- **Observação**: um registro que nunca é confirmado é limpo automaticamente após 24 horas.\n\nErros de negócio documentados: `39001`, `39011`, `39014`, `39041`, `39046`, `39047`. Consulte [Error Codes](../Getting%20Started/error-codes.md) para o significado de cada código. Qualquer operação também pode retornar os códigos comuns.",
        "operationId": "confirmCloudStorageUploadComplete",
        "tags": [
          "Cloud Storage Files"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadCompleteRequest"
              },
              "example": {
                "id": "1800000000000001"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/UploadCompleteResponse"
          }
        }
      }
    },
    "/cloudstorage/file/delete/batch": {
      "post": {
        "summary": "Excluir em lote arquivos do armazenamento em nuvem",
        "description": "Exclui arquivos do Cloud Storage por identificador.\n- **Pré-requisitos**: todos os identificadores precisam ser resolvidos dentro da sua equipe; **se um único não for, o lote inteiro é rejeitado e revertido**, inclusive identificadores que já estavam excluídos.\n- **Efeito**: é uma exclusão lógica. A cota é liberada na mesma transação e os objetos armazenados são removidos na medida do possível; uma falha do armazenamento é registrada em log, mas não faz a chamada falhar, então um objeto pode sobreviver ao registro dele. Os vínculos de etiquetas não são limpos.\n- **Conclusão**: sincrônica. Confirme o espaço liberado com `/cloudstorage/info`.\n\nErros de negócio documentados: `39011`. Consulte [Error Codes](../Getting%20Started/error-codes.md) para o significado de cada código. Qualquer operação também pode retornar os códigos comuns.",
        "operationId": "batchDeleteCloudStorageFiles",
        "tags": [
          "Cloud Storage Files"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileDeleteRequest"
              },
              "example": {
                "ids": [
                  "1800000000001001",
                  "1800000000001002"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/VoidDataResponse"
          }
        }
      }
    },
    "/cloudstorage/file/tag/set": {
      "post": {
        "summary": "Definir etiquetas de arquivo",
        "description": "Substitui as etiquetas de um arquivo do Cloud Storage.\n- **Pré-requisitos**: um `fileId` por chamada, e `tagIds` não pode estar vazio e precisa referenciar etiquetas de Cloud Storage que pertençam à sua equipe. As etiquetas de perfis são rejeitadas.\n- **Efeito**: as etiquetas ausentes da solicitação são removidas do arquivo e as que faltam são adicionadas. **Aqui não há como remover todas as etiquetas**, porque uma lista vazia é rejeitada.\n- **Conclusão**: sincrônica e idempotente para o mesmo corpo.\n\nErros de negócio documentados: `39011`, `39048`, `39049`. Consulte [Error Codes](../Getting%20Started/error-codes.md) para o significado de cada código. Qualquer operação também pode retornar os códigos comuns.",
        "operationId": "setCloudStorageFileTags",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileTagChangeRequest"
              },
              "example": {
                "fileId": "1800000000001001",
                "tagIds": [
                  "1800000000000101",
                  "1800000000000102"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/VoidDataResponse"
          }
        }
      }
    },
    "/cloudstorage/file/tag/add": {
      "post": {
        "summary": "Adicionar etiquetas de arquivo",
        "description": "Adiciona etiquetas a um arquivo do Cloud Storage sem remover as existentes.\n- **Pré-requisitos**: um `fileId` por chamada, e `tagIds` não pode estar vazio e precisa referenciar etiquetas de Cloud Storage que pertençam à sua equipe.\n- **Efeito**: apenas adiciona; as etiquetas existentes permanecem. Use a variante de substituição para trocá-las.\n- **Conclusão**: sincrônica e idempotente; adicionar uma etiqueta que o arquivo já tem não muda nada.\n\nErros de negócio documentados: `39011`, `39048`, `39049`. Consulte [Error Codes](../Getting%20Started/error-codes.md) para o significado de cada código. Qualquer operação também pode retornar os códigos comuns.",
        "operationId": "addCloudStorageFileTags",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileTagChangeRequest"
              },
              "example": {
                "fileId": "1800000000001001",
                "tagIds": [
                  "1800000000000103"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/VoidDataResponse"
          }
        }
      }
    },
    "/cloudstorage/file/tag/query": {
      "post": {
        "summary": "Consultar etiquetas de arquivo",
        "description": "Retorna as etiquetas vinculadas a um ou mais arquivos do Cloud Storage.\n- **Pré-requisitos**: todos os `fileId` precisam ser resolvidos dentro da sua equipe; **um único identificador desconhecido faz a chamada inteira falhar** em vez de retornar dados parciais.\n- **Efeito**: nenhum. Somente leitura. É seguro repetir com recuo limitado.\n- **Ressalva**: `tagIds` é lido dos vínculos, enquanto os detalhes das etiquetas vêm das etiquetas vigentes, então uma etiqueta excluída enquanto ainda estava vinculada aparece em `tagIds` sem entrada correspondente nos detalhes. As duas listas podem ter tamanhos diferentes.",
        "operationId": "queryCloudStorageFileTags",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileTagQueryRequest"
              },
              "example": {
                "fileIds": [
                  "1800000000001001"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/FileTagsResponse"
          }
        }
      }
    },
    "/cloudstorage/tag/all": {
      "get": {
        "summary": "Consultar todas as etiquetas de arquivo do Cloud Storage",
        "description": "Retorna todas as etiquetas de arquivo do Cloud Storage da equipe.\n- **Efeito**: nenhum. Somente leitura. É seguro repetir com recuo limitado.\n- **Observação**: não é paginado e as etiquetas de Cloud Storage não têm limite de quantidade no servidor, então a resposta cresce com o número de etiquetas que a sua equipe criar.",
        "operationId": "queryAllCloudStorageFileTags",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/TagListResponse"
          }
        }
      }
    },
    "/cloudstorage/tag/create": {
      "post": {
        "summary": "Criar etiqueta de arquivo do Cloud Storage",
        "description": "Cria uma etiqueta de arquivo do Cloud Storage.\n- **Pré-requisitos**: `tagName` não pode estar em branco.\n- **Efeito**: cria a etiqueta com uma cor escolhida de uma paleta fixa. **Não há verificação de nome duplicado e não há limite de quantidade**, então repetir a chamada cria uma segunda etiqueta com o mesmo nome.\n- **Conclusão**: sincrônica; a resposta traz a etiqueta nova.",
        "operationId": "createCloudStorageFileTag",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TagCreateRequest"
              },
              "example": {
                "tagName": "Invoice"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/TagResponse"
          }
        }
      }
    },
    "/cloudstorage/tag/edit": {
      "post": {
        "summary": "Editar etiqueta de arquivo do Cloud Storage",
        "description": "Renomeia uma etiqueta de arquivo do Cloud Storage.\n- **Pré-requisitos**: a etiqueta precisa existir na sua equipe e ser uma etiqueta de Cloud Storage.\n- **Efeito**: apenas o nome muda; a cor e todos os vínculos existentes são mantidos, então os arquivos mostram o nome novo imediatamente.\n- **Conclusão**: sincrônica. Sem bloqueio otimista: renomeações simultâneas são resolvidas pela última escrita.",
        "operationId": "editCloudStorageFileTag",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TagEditRequest"
              },
              "example": {
                "id": "1800000000000101",
                "tagName": "Invoice 2026"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/BooleanDataResponse"
          }
        }
      }
    },
    "/cloudstorage/tag/delete/batch": {
      "post": {
        "summary": "Excluir etiquetas de arquivo do Cloud Storage",
        "description": "Exclui etiquetas de arquivo do Cloud Storage.\n- **Pré-requisitos**: todos os identificadores precisam ser etiquetas de Cloud Storage da sua equipe; **um único identificador inválido faz o lote inteiro falhar**.\n- **Efeito**: as etiquetas são excluídas, mas **os vínculos delas com arquivos não são limpos**. Espere duas consequências: `/cloudstorage/file/tag/query` continua retornando o identificador da etiqueta excluída sem detalhe correspondente, e `tagInfo` em `/cloudstorage/file/page` pode conter entradas null. Filtrar arquivos pelo identificador de uma etiqueta excluída não retorna nada.\n- **Conclusão**: sincrônica, e não está envolvida em uma transação.",
        "operationId": "deleteCloudStorageFileTags",
        "tags": [
          "Cloud Storage File Tags"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TagDeleteRequest"
              },
              "example": {
                "ids": [
                  "1800000000000101",
                  "1800000000000102"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/BooleanDataResponse"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "Authorization": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    },
    "schemas": {
      "ApiResponseBase": {
        "type": "object",
        "properties": {
          "code": {
            "type": "integer",
            "description": "Código de resultado. `0` significa sucesso; outros códigos indicam exceções.",
            "example": 0
          },
          "msg": {
            "type": [
              "string",
              "null"
            ],
            "description": "Mensagem de erro.",
            "example": null
          },
          "requestId": {
            "type": "string",
            "description": "ID da requisição da operação. Este campo pode estar presente quando a requisição passa pelo gateway da API.",
            "example": "1d4f3ea968664593860b94b35d4ebf5e"
          }
        },
        "required": [
          "code",
          "msg"
        ]
      },
      "StorageInfo": {
        "type": "object",
        "properties": {
          "capacity": {
            "type": "string",
            "description": "Capacidade total de armazenamento na nuvem em bytes.",
            "example": "10737418240"
          },
          "usedCapacity": {
            "type": "string",
            "description": "Capacidade de armazenamento na nuvem usada em bytes.",
            "example": "536870912"
          },
          "expireDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
            "description": "Data de expiração do armazenamento na nuvem."
          },
          "capacityStatus": {
            "type": "integer",
            "description": "Status da capacidade: 0 = normal, 1 = cheia.",
            "example": 0
          },
          "isExpired": {
            "type": "boolean",
            "description": "Se o plano de assinatura expirou.",
            "example": false
          }
        }
      },
      "CloudStorageFile": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID do arquivo do armazenamento em nuvem.",
            "example": "1800000000001001"
          },
          "fileName": {
            "type": "string",
            "description": "Nome do arquivo (sem extensão).",
            "example": "example"
          },
          "fileExt": {
            "type": "string",
            "description": "Extensão do arquivo.",
            "example": "jpg"
          },
          "fileSize": {
            "type": "string",
            "description": "Tamanho do arquivo em bytes.",
            "example": "204800"
          },
          "fileType": {
            "type": "integer",
            "description": "Tipo de arquivo: 0 = imagem, 1 = vídeo, 2 = aplicativo, 3 = áudio, 4 = documento, 5 = outro.",
            "example": 0
          },
          "tagInfo": {
            "type": "array",
            "description": "Detalhes das etiquetas associadas ao arquivo.",
            "items": {
              "$ref": "#/components/schemas/TagInfo"
            }
          },
          "createDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
            "description": "Data de envio."
          },
          "updateDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
            "description": "Data de atualização."
          }
        }
      },
      "TagInfo": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID da tag.",
            "example": "1800000000000101"
          },
          "tagSource": {
            "type": "string",
            "description": "Origem da etiqueta, por exemplo ENV, PROXY.",
            "example": "ENV"
          },
          "tagName": {
            "type": "string",
            "description": "Nome da tag.",
            "example": "Invoice"
          },
          "tagType": {
            "type": "string",
            "description": "Tipo de etiqueta: TAG ou GROUP.",
            "example": "TAG"
          },
          "tagIcon": {
            "type": "string",
            "description": "Ícone da etiqueta.",
            "example": ""
          }
        }
      },
      "FilePageRequest": {
        "type": "object",
        "properties": {
          "pageNo": {
            "type": "integer",
            "description": "Número da página atual, começando em 1. O padrão é 1.",
            "minimum": 1,
            "default": 1,
            "example": 1
          },
          "pageSize": {
            "type": "integer",
            "description": "Número de itens por página. O padrão é 10.",
            "minimum": 1,
            "default": 10,
            "example": 20
          },
          "fileName": {
            "type": "string",
            "description": "Palavra-chave do nome do arquivo para busca aproximada.",
            "example": "report"
          },
          "tagIds": {
            "type": "array",
            "description": "Filtra os arquivos por IDs de etiqueta.",
            "items": {
              "type": "string"
            },
            "example": [
              "1800000000000101"
            ]
          },
          "fileType": {
            "type": "integer",
            "description": "Filtro por tipo de arquivo: 0 = imagem, 1 = vídeo, 2 = aplicativo, 3 = áudio, 4 = documento, 5 = outro.",
            "example": 0
          },
          "fileIds": {
            "type": "array",
            "description": "Filtra os arquivos por IDs de arquivo.",
            "items": {
              "type": "string"
            },
            "example": [
              "1800000000001001"
            ]
          }
        }
      },
      "FilePageData": {
        "type": "object",
        "properties": {
          "current": {
            "type": "string",
            "example": "1"
          },
          "pages": {
            "type": "string",
            "example": "7"
          },
          "total": {
            "type": "string",
            "example": "128"
          },
          "dataList": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CloudStorageFile"
            }
          }
        },
        "required": [
          "current",
          "pages",
          "total",
          "dataList"
        ]
      },
      "UploadInitRequest": {
        "type": "object",
        "properties": {
          "fileNames": {
            "type": "array",
            "minItems": 1,
            "description": "Lista de nomes de arquivos a enviar (com extensão), por exemplo photo.jpg, video.mp4.",
            "items": {
              "type": "string"
            },
            "example": [
              "photo.jpg",
              "video.mp4"
            ]
          }
        },
        "required": [
          "fileNames"
        ]
      },
      "UploadInitResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID do arquivo do armazenamento em nuvem.",
            "example": "1800000000000001"
          },
          "fileName": {
            "type": "string",
            "description": "Nome do arquivo (com extensão).",
            "example": "photo.jpg"
          },
          "presignedUrl": {
            "type": "string",
            "description": "URL pré-assinada do S3 para envio. Use HTTPS PUT para enviar o conteúdo do arquivo.",
            "example": "https://example.com/presigned-upload-url"
          }
        }
      },
      "UploadCompleteRequest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID do arquivo do Cloud Storage retornado pela API de URL pré-assinada de envio.",
            "example": "1800000000000001"
          }
        },
        "required": [
          "id"
        ]
      },
      "FileDeleteRequest": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string"
            },
            "description": "IDs dos arquivos do Cloud Storage a serem excluídos.",
            "example": [
              "1800000000001001",
              "1800000000001002"
            ]
          }
        },
        "required": [
          "ids"
        ]
      },
      "FileTagChangeRequest": {
        "type": "object",
        "properties": {
          "fileId": {
            "type": "string",
            "description": "ID do arquivo do armazenamento em nuvem.",
            "example": "1800000000001001"
          },
          "tagIds": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string"
            },
            "description": "IDs de tags.",
            "example": [
              "1800000000000101",
              "1800000000000102"
            ]
          }
        },
        "required": [
          "fileId",
          "tagIds"
        ]
      },
      "FileTagQueryRequest": {
        "type": "object",
        "properties": {
          "fileIds": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string"
            },
            "description": "IDs de arquivos do Cloud Storage.",
            "example": [
              "1800000000001001"
            ]
          }
        },
        "required": [
          "fileIds"
        ]
      },
      "FileTagResultData": {
        "type": "object",
        "properties": {
          "fileId": {
            "type": "string",
            "description": "ID do arquivo do armazenamento em nuvem.",
            "example": "1800000000001001"
          },
          "tagIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "IDs das etiquetas associadas ao arquivo.",
            "example": [
              "1800000000000101"
            ]
          },
          "tagInfo": {
            "type": "array",
            "description": "Detalhes das etiquetas.",
            "items": {
              "$ref": "#/components/schemas/TagInfo"
            }
          }
        }
      },
      "TagCreateRequest": {
        "type": "object",
        "properties": {
          "tagName": {
            "type": "string",
            "description": "Nome da tag.",
            "example": "Invoice"
          }
        },
        "required": [
          "tagName"
        ]
      },
      "TagEditRequest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID da tag.",
            "example": "1800000000000101"
          },
          "tagName": {
            "type": "string",
            "description": "Nome da tag.",
            "example": "Invoice 2026"
          }
        },
        "required": [
          "id",
          "tagName"
        ]
      },
      "TagDeleteRequest": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string"
            },
            "description": "IDs das etiquetas a excluir.",
            "example": [
              "1800000000000101"
            ]
          }
        },
        "required": [
          "ids"
        ]
      }
    },
    "responses": {
      "StorageInfoResponse": {
        "description": "Sucesso",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/StorageInfo"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "FilePageResponse": {
        "description": "Sucesso",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FilePageData"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "UploadInitResponse": {
        "description": "Sucesso",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/UploadInitResult"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "UploadCompleteResponse": {
        "description": "Sucesso",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CloudStorageFile"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "VoidDataResponse": {
        "description": "Sucesso",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "null",
                      "example": null
                    }
                  }
                }
              ]
            }
          }
        }
      },
      "BooleanDataResponse": {
        "description": "Sucesso",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "boolean",
                      "example": true
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "FileTagsResponse": {
        "description": "Sucesso",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FileTagResultData"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "TagListResponse": {
        "description": "Sucesso",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TagInfo"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      },
      "TagResponse": {
        "description": "Sucesso",
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ApiResponseBase"
                },
                {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/TagInfo"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              ]
            }
          }
        }
      }
    }
  },
  "security": [
    {
      "Authorization": []
    }
  ]
}